use salvo::{macros::Extractible, oapi::ToSchema};
use serde::{Deserialize, Serialize};
use validator::{Validate, ValidationError};

use crate::entities::files::File;

#[derive(Debug, Deserialize,Extractible,ToSchema, Validate, Default)]
// #[salvo(extract(default_source(from = "url")))]
pub struct FileAddRequest {
    #[salvo(extract(source(from = "param")))]
    pub id: String, // paper_id
    #[salvo(extract(source(from = "query")))]
    pub file_name: String,
    #[validate(custom(function = "validate_file_type"))]
    #[salvo(extract(source(from = "query")))]
    pub file_type: String,
    // pub data: Vec<u8>,
}

fn validate_file_type(file_type: &str) -> Result<(), ValidationError> {
    static VALIDATE_FILE_TYPE: [&str; 2] = ["txt", "pdf"];
    let file_type = file_type.to_lowercase();
    if VALIDATE_FILE_TYPE.contains(&file_type.as_str()) {
        Ok(())
    } else {
        return Err(ValidationError::new("file_type is invalid"));
    }
}

#[derive(Debug, Deserialize,Extractible,ToSchema, Default)]
pub struct FileAddRequestQuick {
    #[salvo(extract(source(from = "param")))]
    pub id: String, // paper_id
    #[salvo(extract(source(from = "param")))]
    pub hash: String,
    #[salvo(extract(source(from = "query")))]
    pub file_name: String,
}

#[derive(Debug, Deserialize,Extractible,ToSchema, Default)]
#[salvo(extract(default_source(from = "param")))]
pub struct FileDownloadRequest {
    pub id: String, // paper_id
    pub hash: String, // file_hash
}

#[derive(Debug, Deserialize,Extractible,ToSchema, Default)]
#[salvo(extract(default_source(from = "param")))]
pub struct FileDeleteRequest {
    pub id: String, // paper_id
    pub hash: String, // file_hash
}

#[derive(Debug, Serialize, ToSchema, Default, Clone)]
pub struct FileResponse {
    pub paper_id: String,
    pub file_name: String,
    pub file_type: String,
    pub file_hash: String
}

impl From<FileResponse> for File {
    fn from(value: FileResponse) -> Self {
        Self {
            file_hash: value.file_hash,
            file_type: value.file_type,
        }
    }
}